/**
 * 
 */
package cn.edu.cqu.bysj.wm.ago.anlys;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;

import cn.edu.cqu.bysj.wm.ago.lp.LPCommunity;
import cn.edu.cqu.bysj.wm.def.ConstDef;
import cn.edu.cqu.bysj.wm.neo4j.Neo4jTraversal;

/**
 * @author Meng
 * 
 */
public class Strength {

	private static Direction direction;
	
	// map of community id and its strength
	public static Map<Long, Integer> strengths;

	/**
	 * judge is the communitys detected belong to strong community or week
	 * community or neither
	 * 
	 * @param communitys
	 * @param direction
	 * @return map of community and it's strength property
	 */
	public static void judge(Direction direction, int type) {
		
		Strength.direction = direction;
		strengths = new HashMap<Long, Integer>();

		Map<Long, List<Node>> communitys;
		if (type == ConstDef.LP) {
			communitys = LPCommunity.communitys;
		} else {
			communitys = ModularityGN.result;
		}

		for (long cid : communitys.keySet()) {
			// judge strong community property
			if (StrongCommunity(communitys.get(cid))) {
				strengths.put(cid, ConstDef.STRONG_COMMUNITY);

				// not belong to strong communtiy then judge week community
				// property
			} else if (WeekCommunity(communitys.get(cid))) {
				strengths.put(cid, ConstDef.WEAK_COMMUNITY);

				// neither above
			} else {
				strengths.put(cid, ConstDef.NEITHER);
			}
		}
	}

	/**
	 * judge if is strong community
	 * 
	 * @param nodes
	 * @return true or false
	 */
	private static boolean StrongCommunity(List<Node> nodes) {

		boolean ans = true;

		for (Node node : nodes) {
			int in = Neo4jTraversal.getRelationshipsInCommunity(node, nodes);
			int out = Neo4jTraversal.getRelationshipsOutCommunity(node,
					nodes, direction);

			// any of the nodes break the rule return false;
			if (in < out) {
				ans = false;
				break;
			}
		}

		return ans;
	}

	/**
	 * judge if is week community
	 * 
	 * @param nodes
	 * @return true or false
	 */
	private static boolean WeekCommunity(List<Node> nodes) {

		int in = Neo4jTraversal.getRelationshipsInCommunity(nodes);
		int out = Neo4jTraversal.getRelationshipsOutCommunity(nodes,
				direction);
		return in >= out ? true : false;
	}
}
